#ifndef __R8B_SPRITE_H__
#define __R8B_SPRITE_H__
#include <math.h>
#include <SDL/SDL.h>

#ifdef __cplusplus
extern "C" {
#endif

//! \brief Does the sprite own its surfaces?
#define R8B_SPRITE_FLAG_OWN_SURFACES 0x0001

/*! \brief Sprite structure
 * 
 * This structure will store different surfaces for the animation and
 * other important stuff for the sprite.
 */
typedef struct R8B_Sprite {
  Uint32 start_tick; //!< at which point in time was the sprite created?
  SDL_Surface **surface_ptr; //!< array of sprite surfaces
  Uint32 flags; //!< flags for this sprite
  Uint16 surface_count; //!< how many surfaces are there?
  Uint16 speed_divisor; //!< internal speed divisor for the animation
  Sint16 to_x; //!< position to move sprite to
  Sint16 to_y; //!< position to move sprite to
  double x; //!< x position of the sprite for the higher level functions
  double y; //!< y position of the sprite for the higher level functions
  Uint32 last_tick; //!< last tick from SDL_GetTicks()
  double delta_x; //!< speed per ms/tick
  double delta_y; //!< speed per ms/tick
} R8B_Sprite;


/*! \brief Create a sprite struct
 *
 * This will allocate memory for the sprite structure. It will *not*
 * allocate memory for the surfaces!
 *
 * \param surfaces pointer to an array of surfaces
 * \param surface_count number of surfaces in this array
 * \param delay delay in ms for each frame
 * \param now return from SDL_GetTicks
 */
R8B_Sprite *r8b_createSprite(Uint32 now,
			     SDL_Surface **surfaces,
			     Uint16 surface_count, Uint16 delay);

/*! \brief Destroy a sprite structure
 *
 * This function will deallocate the memory of the surfaces iff the
 * appropriate flag is set.
 *
 * \param sprite sprite structure to destroy
 */
void r8b_destroySprite(R8B_Sprite *sprite);


/*! \brief Draw a sprite
 *
 * It will draw a sprite while animating it.
 *
 * \param sprite pointer to a sprite struct
 * \param now return from SDL_GetTicks, used for selecting the frame
 * \param dst target surface
 * \param dstpos destination rectangle
 * \return return value of SDL_BlitSurface
 */
int r8b_drawSprite(R8B_Sprite *sprite, Uint32 now, SDL_Surface *dst, SDL_Rect *dstpos);

/*! \brief Draw a sprite with all necessary updates
 *
 * It will draw a sprite while animating it. This function uses all
 * necessary information from the sprite, e.g. the position. So
 * movement can be easily created using r8b_warpSprite and
 * drawUpdateSprite.
 *
 * \param sprite pointer to a sprite struct
 * \param now return from SDL_GetTicks, used for selecting the frame
 * \param dst target surface
 * \param dstpos destination rectangle
 * \return return value of SDL_BlitSurface
 */
int r8b_drawUpdateSprite(R8B_Sprite *sprite, Uint32 now, SDL_Surface *dst);

/*! \brief get current image
 * \param sprite sprite pointer
 * \param now return from SDL_GetTicks
 * \return the current surface
 */
SDL_Surface *r8b_getCurrentSpriteSurface(R8B_Sprite *sprite, Uint32 now);

/*! Initialise a sprite struct
 *
 * \param sprite pointer to a sprite structure which is initialised
 * \param surfaces pointer to an array of surfaces
 * \param surface_count number of surfaces in this array
 * \param delay delay in ms for each frame
 * \param now return from SDL_GetTicks
 */
void r8b_initSprite(R8B_Sprite *sprite, Uint32 now,
		    SDL_Surface **surfaces,
		    Uint16 surface_count, Uint16 delay);

/*! \brief Set the sprite in motion
 *
 * \param sprite sprite pointer
 * \param x position to move to
 * \param y position to move to
 * \param speed as per ms/tick
 * \return distance in pixel
 */
double r8b_moveSpriteTo(R8B_Sprite *sprite, Sint16 x, Sint16 y, double speed);

/*! \brief warp a sprite to position
 *
 * \param sprite the sprite
 * \param x the position to warp the sprite to
 * \param y the position to warp the sprite to
 */
void r8b_warpSprite(R8B_Sprite *sprite, Sint16 x, Sint16 y);

#ifdef __cplusplus
}
#endif

#endif
